/*
 * aodv_core.c
 * 
 * AODV (Ad-hoc On-demand Distance Vector)路由协议核心实现
 * 该文件包含AODV协议的主要功能模块，包括协议初始化、数据发送处理、
 * 路由发现、控制消息处理和链路故障恢复等功能。
 */

#include "aodv.h"
#include "aodv_types.h"
#include "net_interface.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 定义HELLO消息类型
#define MESSAGE_TYPE_HELLO 5

// HELLO消息结构体定义
typedef struct {
    uint8_t type;                  // 消息类型
    uint8_t flags;                 // 标志位
    uint8_t reserved;              // 保留字段
    uint8_t hop_count;             // 跳数
    uint32_t destination_ip;       // 目标IP
    uint32_t destination_seq_num;  // 目标序列号
    uint32_t originator_ip;        // 源IP
    uint32_t lifetime;             // 生命周期
} hello_message_t;

// AODV全局状态变量定义
static uint32_t my_ip = 0;             // 当前节点IP地址

// AODV协议配置参数
static aodv_config_t aodv_config = {
    1000,    // hello_interval (1秒) - HELLO消息发送间隔
    2,       // allowed_hello_loss (允许丢失2个HELLO) - 邻居节点失效判定阈值
    30000,   // active_route_timeout (30秒) - 活动路由超时时间
    30,      // net_diameter - 网络最大直径，用于计算路由超时时间
    200,     // node_traversal_time (200毫秒) - 节点间包传输时间估计
    1000,    // rreq_retry_timeout (1秒) - 路由请求重试超时时间
    3,       // max_rreq_retries - 最大路由请求重试次数
    2000     // path_expiry_time (2秒) - 路径过期时间
};

static uint32_t current_seq_num = 1;   // 当前节点序列号，递增用于路由更新
static uint32_t last_rreq_id = 0;      // 最后使用的RREQ ID，用于路由请求标识

// 最大待处理路由数量
#define MAX_PENDING_ROUTES 20

// 待处理路由结构，用于管理路由发现过程中的重试和超时
static struct {
    uint32_t destination_ip;  // 目标IP地址
    int rreq_retries;         // 已进行的RREQ重试次数
    uint32_t expiration_time; // 超时时间
} pending_routes[MAX_PENDING_ROUTES];

// RREQ ID记录表（用于检测重复的路由请求消息，避免循环转发）
#define MAX_RREQ_ID_RECORDS 50  // 最大记录数量，防止内存溢出
static struct {
    uint32_t source_ip;  // 路由请求源IP地址
    uint32_t rreq_id;    // 路由请求标识符
    uint32_t timestamp;  // 记录时间戳，用于老化处理
} rreq_id_records[MAX_RREQ_ID_RECORDS];
static int rreq_id_record_count = 0;  // 当前记录数量

/**
 * @brief 初始化AODV协议栈
 * 
 * 初始化AODV协议相关的状态变量、网络接口，并设置必要的定时器
 * 
 * @param ip 当前节点的IP地址
 * @param config 可选的AODV配置参数，如果为NULL则使用默认配置
 * @return 成功返回0，失败返回负值
 */
int aodv_init(uint32_t ip, const aodv_config_t *config) {
    my_ip = ip;  // 设置当前节点IP地址
    
    // 如果提供了自定义配置，使用配置值
    if (config != NULL) {
        memcpy(&aodv_config, config, sizeof(aodv_config_t));
    }
    
    // 初始化网络接口，准备数据收发
    net_interface_init(my_ip);
    
    // 设置网络接口接收回调函数，处理所有接收到的数据包
    net_interface_set_receive_callback(aodv_handle_rx_packet);
    
    // 创建并启动HELLO定时器，用于定期发送HELLO消息维护邻居关系
    timer_create(TIMER_HELLO, aodv_config.hello_interval, NULL);
    timer_start(1); // 假设HELLO定时器ID为1
    
    printf("AODV protocol initialized with IP: %d.%d.%d.%d\n", 
           (my_ip >> 24) & 0xFF, (my_ip >> 16) & 0xFF, 
           (my_ip >> 8) & 0xFF, my_ip & 0xFF);
    
    return 0;
}

/**
 * @brief 清理AODV协议栈资源
 * 
 * 释放AODV协议栈使用的所有资源，包括网络接口、定时器等
 */
void aodv_cleanup(void) {
    // 清理网络接口资源，关闭网络连接
    net_interface_cleanup();
    
    // 清理其他资源...（例如定时器、内存等）
    printf("AODV protocol cleaned up\n");
}

/**
 * @brief 发送数据到指定目标IP
 * 
 * 检查路由表中是否存在到目标的路由，如果存在则直接发送数据；
 * 如果不存在，则发起路由发现过程
 * 
 * @param dest_ip 目标IP地址
 * @param data 要发送的数据
 * @param data_len 数据长度（字节）
 * @return 成功返回0，失败返回负值
 */
int aodv_send_data(uint32_t dest_ip, const void *data, size_t data_len) {
    // 在路由表中查找到目标IP的路由条目
    route_table_entry_t *entry = route_table_find(dest_ip);
    
    if (entry != NULL) {
        // 路由存在，通过下一跳发送数据
        printf("Sending data to %d.%d.%d.%d via %d.%d.%d.%d\n",
               (dest_ip >> 24) & 0xFF, (dest_ip >> 16) & 0xFF, 
               (dest_ip >> 8) & 0xFF, dest_ip & 0xFF,
               (entry->next_hop_ip >> 24) & 0xFF, (entry->next_hop_ip >> 16) & 0xFF, 
               (entry->next_hop_ip >> 8) & 0xFF, entry->next_hop_ip & 0xFF);
        
        // 将数据发送到路由表中记录的下一跳节点
        // 注意：AODV是逐跳转发的，每个节点只负责将数据转发到下一跳
        return net_interface_send(entry->next_hop_ip, PROTOCOL_DATA, data, data_len);
    } else {
        // 路由不存在，需要发起路由发现过程
        printf("No route to %d.%d.%d.%d, initiating route discovery\n",
               (dest_ip >> 24) & 0xFF, (dest_ip >> 16) & 0xFF, 
               (dest_ip >> 8) & 0xFF, dest_ip & 0xFF);
        
        // 发起路由发现请求（RREQ）
        if (initiate_route_discovery(dest_ip) != 0) {
            return -1;
        }
        
        // 简化实现：在实际应用中，应该将数据缓存在发送队列中，
        // 等待路由建立成功后再发送
        printf("Data will be sent after route is established\n");
        return 0;
    }
}

/**
 * @brief 处理接收到的数据包
 * 
 * 这是网络接口的回调函数，用于处理所有接收到的数据包，根据协议类型进行分发处理
 * 
 * @param src_ip 发送方IP地址
 * @param protocol 协议类型（PROTOCOL_AODV或PROTOCOL_DATA）
 * @param data 数据包内容
 * @param data_len 数据包长度
 * @return 成功返回0，失败返回负值
 */
int aodv_handle_rx_packet(uint32_t src_ip, uint8_t protocol, const void *data, size_t data_len) {
    // 接收到任何数据包时，更新发送方在邻居表中的状态
    // 这是AODV协议维护邻居关系的关键机制之一
    neighbor_table_update(src_ip);
    
    // 根据协议类型分发处理
    if (protocol == PROTOCOL_AODV) {
        // 处理AODV控制消息（RREQ、RREP、RERR等）
        return aodv_handle_control_message(src_ip, data, data_len);
    } else if (protocol == PROTOCOL_DATA) {
        // 处理数据消息
        if (src_ip == my_ip) {
            // 数据包是发给自己的，直接处理
            printf("Received data packet from %d.%d.%d.%d, length: %u\n",
                   (src_ip >> 24) & 0xFF, (src_ip >> 16) & 0xFF, 
                   (src_ip >> 8) & 0xFF, src_ip & 0xFF,
                   (unsigned int)data_len);
            return 0;
        } else {
            // 数据包需要转发，查找路由表获取转发路径
            // 注意：此处有逻辑错误，应该根据数据包的目标地址而非源地址查找路由
            // 在实际应用中需要修正这个问题
            route_table_entry_t *entry = route_table_find(src_ip);
            if (entry != NULL) {
                // 转发数据包到路由表指定的下一跳
                printf("Forwarding data packet from %d.%d.%d.%d to %d.%d.%d.%d\n",
                       (src_ip >> 24) & 0xFF, (src_ip >> 16) & 0xFF, 
                       (src_ip >> 8) & 0xFF, src_ip & 0xFF,
                       (entry->next_hop_ip >> 24) & 0xFF, (entry->next_hop_ip >> 16) & 0xFF, 
                       (entry->next_hop_ip >> 8) & 0xFF, entry->next_hop_ip & 0xFF);
                return net_interface_send(entry->next_hop_ip, PROTOCOL_DATA, data, data_len);
            } else {
                // 没有找到转发路由，丢弃数据包
                printf("No route to forward data packet to %d.%d.%d.%d\n",
                       (src_ip >> 24) & 0xFF, (src_ip >> 16) & 0xFF, 
                       (src_ip >> 8) & 0xFF, src_ip & 0xFF);
                return -1;
            }
        }
    }
    
    // 未知协议类型，返回错误
    return -1;
}

/**
 * @brief 处理接收到的AODV控制消息
 * 
 * 根据消息类型将AODV控制消息分发给对应的处理函数
 * AODV协议定义了四种主要控制消息：RREQ(路由请求)、RREP(路由回复)、
 * RERR(路由错误)和RREP_ACK(路由回复确认)
 * 
 * @param src_ip 发送方IP地址
 * @param data 消息内容
 * @param data_len 消息长度
 * @return 成功返回0，失败返回负值
 */
int aodv_handle_control_message(uint32_t src_ip, const void *data, size_t data_len) {
    // 基本的消息长度检查，确保至少有一个字节的消息类型
    if (data_len < 1) {
        printf("Invalid AODV message: too short\n");
        return -1;
    }
    
    // 提取消息类型（消息的第一个字节）
    uint8_t message_type = *((uint8_t *)data);
    
    // 根据消息类型分发到对应的处理函数
    switch (message_type) {
        case MESSAGE_TYPE_RREQ:
            // 处理路由请求消息
            if (data_len >= sizeof(rreq_message_t)) {
                return handle_rreq_message(src_ip, (rreq_message_t *)data);
            }
            break;
        case MESSAGE_TYPE_RREP:
            // 处理路由回复消息
            if (data_len >= sizeof(rrep_message_t)) {
                return handle_rrep_message(src_ip, (rrep_message_t *)data);
            }
            break;
        case MESSAGE_TYPE_RERR:
            // 处理路由错误消息
            if (data_len >= sizeof(rerr_message_t)) {
                return handle_rerr_message(src_ip, (rerr_message_t *)data);
            }
            break;
        case MESSAGE_TYPE_RREP_ACK:
            // 路由回复确认消息，暂未实现
            break;
        default:
            // 未知消息类型
            printf("Unknown AODV message type: %d\n", message_type);
            break;
    }
    
    return -1;
}

/**
 * @brief 检查路由请求消息是否重复
 * 
 * 通过源IP和RREQ ID组合检查是否接收到重复的路由请求，避免路由循环和网络拥塞
 * 
 * @param source_ip RREQ发送方IP地址
 * @param rreq_id RREQ消息标识符
 * @return 如果是重复RREQ返回1，否则返回0
 */
static int is_duplicate_rreq(uint32_t source_ip, uint32_t rreq_id) {
    // 遍历已记录的RREQ ID列表，检查是否存在相同的源IP和RREQ ID组合
    for (int i = 0; i < rreq_id_record_count; i++) {
        if (rreq_id_records[i].source_ip == source_ip && 
            rreq_id_records[i].rreq_id == rreq_id) {
            return 1; // 重复的RREQ，防止循环转发
        }
    }
    
    // 记录新的RREQ ID，以便将来检测重复
    if (rreq_id_record_count >= MAX_RREQ_ID_RECORDS) {
        // 如果记录数组已满，移除最旧的记录（FIFO策略）
        memmove(rreq_id_records, rreq_id_records + 1, 
                (MAX_RREQ_ID_RECORDS - 1) * sizeof(rreq_id_records[0]));
        rreq_id_record_count--;
    }
    
    // 添加新的RREQ记录
    rreq_id_records[rreq_id_record_count].source_ip = source_ip;
    rreq_id_records[rreq_id_record_count].rreq_id = rreq_id;
    rreq_id_records[rreq_id_record_count].timestamp = get_current_time();
    rreq_id_record_count++;
    
    return 0; // 不是重复的RREQ
}

/**
 * @brief 发起路由发现过程
 * 
 * 创建并广播路由请求消息(RREQ)，启动AODV协议的按需路由发现机制
 * 
 * @param dest_ip 目标节点IP地址
 * @return 成功返回0，失败返回负值
 */
int initiate_route_discovery(uint32_t dest_ip) {
    // 优化：如果目标是自身，无需进行路由发现
    if (dest_ip == my_ip) {
        return 0;
    }
    
    // 创建路由请求消息(RREQ)
    rreq_message_t rreq;
    rreq.type = MESSAGE_TYPE_RREQ;          // 消息类型：路由请求
    rreq.flags = 0;                         // 初始标志位
    memset(rreq.reserved, 0, sizeof(rreq.reserved)); // 清零保留字段
    rreq.rreq_id = ++last_rreq_id;          // 递增并分配RREQ ID，用于标识唯一的路由请求
    rreq.destination_ip = dest_ip;          // 设置目标IP地址
    rreq.destination_seq_num = 0;           // 未知目标序列号，设置为0
    rreq.source_ip = my_ip;                 // 设置源IP地址
    rreq.source_seq_num = current_seq_num++; // 使用并递增当前节点序列号
    rreq.hop_count = 0;                     // 初始跳数为0
    
    // 广播RREQ消息到所有邻居节点
    // 注意：在自组织网络中，广播是通过MAC层广播实现的
    net_interface_broadcast(PROTOCOL_AODV, (void *)&rreq, sizeof(rreq_message_t));
    printf("Initiated route discovery to %d.%d.%d.%d, RREQ ID: %u\n",
           (dest_ip >> 24) & 0xFF, (dest_ip >> 16) & 0xFF, 
           (dest_ip >> 8) & 0xFF, dest_ip & 0xFF,
           rreq.rreq_id);
    
    // 设置RREQ超时定时器，用于在没有收到RREP时重试路由发现
    // 这是AODV协议可靠性机制的一部分
    uint32_t *dest_ip_copy = (uint32_t *)malloc(sizeof(uint32_t));
    if (dest_ip_copy != NULL) {
        *dest_ip_copy = dest_ip; // 保存目标IP，供定时器回调使用
        int timer_id = timer_create(TIMER_RREQ_TIMEOUT, aodv_config.rreq_retry_timeout, dest_ip_copy);
        timer_start(timer_id);
    }
    
    return 0;
}

/**
 * @brief 处理接收到的路由请求消息(RREQ)
 * 
 * 实现AODV协议中RREQ消息的处理逻辑，包括重复检测、反向路由建立、
 * 路由回复生成或请求转发
 * 
 * @param src_ip 发送RREQ的节点IP地址
 * @param rreq RREQ消息结构体指针
 * @return 成功返回0，失败返回负值
 */
int handle_rreq_message(uint32_t src_ip, rreq_message_t *rreq) {
    // 第一步：检查是否是重复的RREQ，避免路由循环和网络拥塞
    if (is_duplicate_rreq(rreq->source_ip, rreq->rreq_id)) {
        printf("Duplicate RREQ received, ignoring\n");
        return -1;
    }
    
    // 打印接收信息，用于调试
    printf("Received RREQ: source=%d.%d.%d.%d, dest=%d.%d.%d.%d, hop_count=%d\n",
           (rreq->source_ip >> 24) & 0xFF, (rreq->source_ip >> 16) & 0xFF, 
           (rreq->source_ip >> 8) & 0xFF, rreq->source_ip & 0xFF,
           (rreq->destination_ip >> 24) & 0xFF, (rreq->destination_ip >> 16) & 0xFF, 
           (rreq->destination_ip >> 8) & 0xFF, rreq->destination_ip & 0xFF,
           rreq->hop_count);
    
    // 场景一：当前节点是目标节点
    if (rreq->destination_ip == my_ip) {
        printf("This node is the destination, sending RREP\n");
        
        // 创建路由回复消息(RREP)
        rrep_message_t rrep;
        rrep.type = MESSAGE_TYPE_RREP;           // 消息类型：路由回复
        rrep.flags = 0;                          // 初始标志位
        rrep.prefix_size = 0;                    // 前缀大小，用于地址聚合
        rrep.hop_count = rreq->hop_count + 1;    // 跳数为RREQ中的跳数+1
        rrep.destination_ip = my_ip;             // 目标IP为自身
        rrep.destination_seq_num = current_seq_num; // 使用当前节点序列号
        rrep.source_ip = rreq->source_ip;        // 源IP为RREQ的源
        rrep.lifetime = aodv_config.active_route_timeout; // 路由生命周期
        
        // 单播发送RREP给源节点（沿着反向路径）
        net_interface_send(src_ip, PROTOCOL_AODV, (void *)&rrep, sizeof(rrep_message_t));
        printf("Sent RREP to %d.%d.%d.%d\n",
               (src_ip >> 24) & 0xFF, (src_ip >> 16) & 0xFF, 
               (src_ip >> 8) & 0xFF, src_ip & 0xFF);
        
        // 为RREQ源节点添加反向路由（记录路由请求的来源路径）
        route_table_entry_t route_entry;
        route_entry.destination_ip = rreq->source_ip;     // 目标是RREQ源节点
        route_entry.next_hop_ip = src_ip;                // 下一跳是发送RREQ的节点
        route_entry.destination_seq_num = rreq->source_seq_num; // 使用RREQ中的序列号
        route_entry.hop_count = 1;                        // 跳数为1
        route_entry.route_flags = ROUTE_FLAG_VALID;       // 路由有效
        route_entry.expiration_time = get_current_time() + aodv_config.active_route_timeout;
        route_entry.active_time = get_current_time();
        route_entry.rreq_retries = 0;
        route_entry.route_type = ROUTE_TYPE_ACTIVE;
        
        route_table_add(&route_entry);
        
        return 0;
    }
    
    // 场景二：检查是否有到目标节点的有效路由（中间节点有更好的路由信息）
    // 只有当我们的路由信息比RREQ中的更新时才生成RREP
    route_table_entry_t *dest_route = route_table_find(rreq->destination_ip);
    if (dest_route != NULL && 
        (dest_route->destination_seq_num > rreq->destination_seq_num ||
         (dest_route->destination_seq_num == rreq->destination_seq_num && 
          rreq->destination_seq_num != 0))) {
        
        printf("Have valid route to destination, sending RREP\n");
        
        // 创建并发送RREP消息，作为中间节点响应路由请求
        rrep_message_t rrep;
        rrep.type = MESSAGE_TYPE_RREP;                   // 消息类型：路由回复
        rrep.flags = 0;                                  // 初始标志位
        rrep.prefix_size = 0;                            // 前缀大小，用于地址聚合
        rrep.hop_count = rreq->hop_count + 1;            // 跳数为RREQ中的跳数+1
        rrep.destination_ip = rreq->destination_ip;      // 目标IP为RREQ的目标
        rrep.destination_seq_num = dest_route->destination_seq_num; // 使用我们知道的目标序列号
        rrep.source_ip = rreq->source_ip;                // 源IP为RREQ的源
        rrep.lifetime = dest_route->expiration_time - get_current_time(); // 剩余生命周期
        
        // 发送RREP给源节点，沿着RREQ的反向路径
        net_interface_send(src_ip, PROTOCOL_AODV, (void *)&rrep, sizeof(rrep_message_t));
        printf("Sent RREP to %d.%d.%d.%d\n",
               (src_ip >> 24) & 0xFF, (src_ip >> 16) & 0xFF, 
               (src_ip >> 8) & 0xFF, src_ip & 0xFF);
        
        // 为RREQ源节点添加反向路由（记录路由请求的来源路径）
        // 这确保后续数据可以正确回传
        route_table_entry_t route_entry;
        route_entry.destination_ip = rreq->source_ip;     // 目标是RREQ源节点
        route_entry.next_hop_ip = src_ip;                // 下一跳是发送RREQ的节点
        route_entry.destination_seq_num = rreq->source_seq_num; // 使用RREQ中的源序列号
        route_entry.hop_count = 1;                        // 跳数为1
        route_entry.route_flags = ROUTE_FLAG_VALID;       // 路由有效
        route_entry.expiration_time = get_current_time() + aodv_config.active_route_timeout; // 路由过期时间
        route_entry.active_time = get_current_time();
        route_entry.rreq_retries = 0;
        route_entry.route_type = ROUTE_TYPE_ACTIVE;
        
        route_table_add(&route_entry);
        
        return 0;  // 成功处理，不需要继续转发RREQ
    }
    
    // 场景三：转发RREQ消息（节点既不是目标，也没有到目标的更好路由）
    // 建立反向路由，确保RREP能正确返回给发起者
    route_table_entry_t route_entry;
    route_entry.destination_ip = rreq->source_ip;     // 目标是RREQ源节点
    route_entry.next_hop_ip = src_ip;                // 下一跳是发送RREQ的节点
    route_entry.destination_seq_num = rreq->source_seq_num; // 使用RREQ中的源序列号
    route_entry.hop_count = rreq->hop_count + 1;      // 跳数为RREQ中的跳数+1
    route_entry.route_flags = ROUTE_FLAG_VALID;       // 路由有效
    route_entry.expiration_time = get_current_time() + aodv_config.active_route_timeout; // 路由过期时间
    route_entry.active_time = get_current_time();
    route_entry.rreq_retries = 0;
    route_entry.route_type = ROUTE_TYPE_ACTIVE;
    
    route_table_add(&route_entry);  // 添加反向路由记录
    
    // 增加跳数并转发RREQ消息
    rreq->hop_count++;  // 增加跳数计数，用于路径长度计算
    net_interface_broadcast(PROTOCOL_AODV, (void *)rreq, sizeof(rreq_message_t));
    printf("Forwarded RREQ, new hop count: %d\n", rreq->hop_count);
    
    return 0;
}

/**
 * @brief 处理接收到的路由回复消息(RREP)
 * 
 * 实现AODV协议中RREP消息的处理逻辑，包括正向路由建立、
 * 路由更新、消息转发以及缓存数据的发送
 * 
 * @param src_ip 发送RREP的节点IP地址
 * @param rrep RREP消息结构体指针
 * @return 成功返回0，失败返回负值
 */
int handle_rrep_message(uint32_t src_ip, rrep_message_t *rrep) {
    // 打印接收信息，用于调试
    printf("Received RREP: source=%d.%d.%d.%d, dest=%d.%d.%d.%d, hop_count=%d\n",
           (rrep->source_ip >> 24) & 0xFF, (rrep->source_ip >> 16) & 0xFF, 
           (rrep->source_ip >> 8) & 0xFF, rrep->source_ip & 0xFF,
           (rrep->destination_ip >> 24) & 0xFF, (rrep->destination_ip >> 16) & 0xFF, 
           (rrep->destination_ip >> 8) & 0xFF, rrep->destination_ip & 0xFF,
           rrep->hop_count);
    
    // 场景一：RREP的目标是当前节点（路由请求发起者）
    if (rrep->destination_ip == my_ip) {
        printf("RREP is for this node, updating route table\n");
        
        // 添加或更新路由表项（建立到目标节点的正向路由）
        route_table_entry_t route_entry;
        route_entry.destination_ip = rrep->source_ip;          // 目标是RREP的源节点
        route_entry.next_hop_ip = src_ip;                     // 下一跳是发送RREP的节点
        route_entry.destination_seq_num = rrep->destination_seq_num; // 使用RREP中的目标序列号
        route_entry.hop_count = rrep->hop_count;               // 跳数为RREP中的跳数
        route_entry.route_flags = ROUTE_FLAG_VALID;            // 路由有效
        route_entry.expiration_time = get_current_time() + rrep->lifetime; // 设置过期时间
        route_entry.active_time = get_current_time();
        route_entry.rreq_retries = 0;
        route_entry.route_type = ROUTE_TYPE_ACTIVE;
        
        route_table_add(&route_entry);
        
        // 停止RREQ超时定时器
        // 注意：这里简化处理，实际应该维护定时器ID与目标的映射关系
        
        printf("Route to %d.%d.%d.%d established\n",
               (rrep->source_ip >> 24) & 0xFF, (rrep->source_ip >> 16) & 0xFF, 
               (rrep->source_ip >> 8) & 0xFF, rrep->source_ip & 0xFF);
        
        return 0;
    }
    
    // 场景二：中间节点转发RREP消息
    // 当收到的RREP不是发给当前节点时，需要转发给目标节点
    route_table_entry_t *route = route_table_find(rrep->destination_ip);
    if (route != NULL) {
        // 递减跳数，因为RREP正在向源节点（RREQ发起者）回传
        rrep->hop_count--;
        
        // 转发RREP给下一跳，继续沿着反向路径向RREQ发起者传播
        net_interface_send(route->next_hop_ip, PROTOCOL_AODV, (void *)rrep, sizeof(rrep_message_t));
        printf("Forwarded RREP to %d.%d.%d.%d\n",
               (route->next_hop_ip >> 24) & 0xFF, (route->next_hop_ip >> 16) & 0xFF, 
               (route->next_hop_ip >> 8) & 0xFF, route->next_hop_ip & 0xFF);
        
        // 建立或更新到RREP源节点（目标节点）的正向路由
        // 这是AODV协议的逐跳学习机制，确保网络中的中间节点能够学习到路由
        route_table_entry_t route_entry;
        route_entry.destination_ip = rrep->source_ip;          // 目标是RREP的源节点（原始目标节点）
        route_entry.next_hop_ip = src_ip;                     // 下一跳是发送RREP的节点
        route_entry.destination_seq_num = rrep->destination_seq_num; // 使用RREP中的目标序列号
        route_entry.hop_count = rrep->hop_count;               // 跳数为递减后的RREP跳数
        route_entry.route_flags = ROUTE_FLAG_VALID;            // 路由有效
        route_entry.expiration_time = get_current_time() + rrep->lifetime; // 设置过期时间
        route_entry.active_time = get_current_time();
        route_entry.rreq_retries = 0;
        route_entry.route_type = ROUTE_TYPE_ACTIVE;
        
        // 添加或更新路由表项
        // 注意：路由表的add操作通常会检查是否已存在相同目标的路由，
        // 如有必要会进行更新（例如使用更优的路由或更新序列号）
        route_table_add(&route_entry);
        
        return 0;
    }
    
    // 如果没有到RREP目标节点的路由，则丢弃消息
    printf("No route to forward RREP to destination %d.%d.%d.%d\n",
           (rrep->destination_ip >> 24) & 0xFF, (rrep->destination_ip >> 16) & 0xFF, 
           (rrep->destination_ip >> 8) & 0xFF, rrep->destination_ip & 0xFF);
    
    return -1;
}

/**
 * @brief 处理接收到的路由错误消息(RERR)
 * 
 * 实现AODV协议中RERR消息的处理逻辑，包括路由失效处理、
 * 路由表更新和错误消息的适当转发
 * 
 * @param src_ip 发送RERR的节点IP地址
 * @param rerr RERR消息结构体指针
 * @return 成功返回0，失败返回负值
 */
int handle_rerr_message(uint32_t src_ip, rerr_message_t *rerr) {
    // 打印接收信息，用于调试
    printf("Received RERR with %d unreachable destinations\n", rerr->dest_count);
    
    // 解析不可达目标列表，RERR消息体后紧跟不可达目标数组
    unreachable_dest_t *dests = (unreachable_dest_t *)((uint8_t *)rerr + sizeof(rerr_message_t));
    
    // 处理每个不可达目标
    for (int i = 0; i < rerr->dest_count; i++) {
        uint32_t dest_ip = dests[i].dest_ip;
        printf("Marking route to %d.%d.%d.%d as unreachable\n",
               (dest_ip >> 24) & 0xFF, (dest_ip >> 16) & 0xFF, 
               (dest_ip >> 8) & 0xFF, dest_ip & 0xFF);
        
        // 场景一：将到不可达目标的路由标记为无效
        // 这是路由错误消息处理的核心步骤，确保节点不会再尝试使用失效的路由
        route_table_invalidate(dest_ip);
        
        // 场景二：重新发起路由发现
        // 当检测到路由失效后，主动发起新的路由发现过程以寻找替代路径
        // 注意：在实际实现中，应该考虑退避策略和重试次数限制
        initiate_route_discovery(dest_ip);
    }
    
    // 场景三：转发RERR消息给可能受影响的节点
    // 这是AODV协议中的路由失效通知机制，确保网络中其他节点能够及时获知路由状态变化
    // 注意：优化实现应该只转发给那些通过当前节点到达不可达目标的节点
    for (int i = 0; i < rerr->dest_count; i++) {
        net_interface_broadcast(PROTOCOL_AODV, (void *)rerr, 
                              sizeof(rerr_message_t) + rerr->dest_count * sizeof(unreachable_dest_t));
    }
    
    return 0;
}

/**
 * @brief 处理链路故障事件
 * 
 * 当检测到与邻居节点的链路断开时，执行故障恢复操作，包括：
 * - 使经过该邻居的所有路由无效
 * - 生成并广播RERR消息通知网络其他节点
 * 
 * @param neighbor_ip 发生链路故障的邻居节点IP地址
 */
void handle_link_failure(uint32_t neighbor_ip) {
    printf("Handling link failure with neighbor: %d.%d.%d.%d\n",
           (neighbor_ip >> 24) & 0xFF, (neighbor_ip >> 16) & 0xFF, 
           (neighbor_ip >> 8) & 0xFF, neighbor_ip & 0xFF);
    
    // 步骤一：使通过该邻居的所有路由无效
    // 当链路故障发生时，所有通过该邻居节点的路由变得不可用
    // 这一步确保节点不会再尝试使用这些失效的路由
    route_table_invalidate_via_neighbor(neighbor_ip);
    
    // 步骤二：生成路由错误消息(RERR)
    // RERR消息用于通知网络中其他节点有关路由失效的信息
    // 这里简化处理，实际应该收集所有受影响的目标
    rerr_message_t rerr;
    rerr.type = MESSAGE_TYPE_RERR;        // 消息类型：路由错误
    rerr.flags = 0;                       // 初始标志位
    memset(rerr.reserved, 0, sizeof(rerr.reserved));  // 清零保留字段
    rerr.dest_count = 1;                  // 简化处理，只包含一个目标
    
    // 步骤三：添加不可达目标信息
    // 在RERR消息中添加因为链路故障而变得不可达的目标信息
    unreachable_dest_t dest;
    dest.dest_ip = neighbor_ip;           // 设置不可达目标IP为故障邻居
    dest.dest_seq_num = 0;                // 简化处理，实际应使用正确的序列号
    
    // 步骤四：分配足够的空间并构建完整的RERR消息
    // 消息包含RERR头部和不可达目标列表
    size_t message_size = sizeof(rerr_message_t) + sizeof(unreachable_dest_t);
    uint8_t *message = (uint8_t *)malloc(message_size);
    if (message != NULL) {
        // 复制RERR头部信息
        memcpy(message, &rerr, sizeof(rerr_message_t));
        // 复制不可达目标信息
        memcpy(message + sizeof(rerr_message_t), &dest, sizeof(unreachable_dest_t));
        
        // 步骤五：广播RERR消息
        // 通过广播方式将路由错误信息传播给网络中的其他节点
        net_interface_broadcast(PROTOCOL_AODV, message, message_size);
        free(message);  // 释放动态分配的内存
    }
}

/**
 * @brief 为指定目标初始化路由发现定时器
 * 
 * 管理路由发现过程中的超时和重试机制，确保在路由未找到时能够
 * 按照配置的时间间隔和重试次数重新发起路由发现请求
 * 
 * @param destination_ip 需要查找路由的目标节点IP地址
 */
void initiate_route_discovery_timer(uint32_t destination_ip) {
    // 检查是否已经有针对该目标的定时器在运行
    for (int i = 0; i < MAX_PENDING_ROUTES; i++) {
        if (pending_routes[i].destination_ip == destination_ip) {
            // 已存在定时器，更新重试计数和超时时间
            pending_routes[i].rreq_retries++;
            pending_routes[i].expiration_time = get_current_time() + aodv_config.rreq_retry_timeout;
            printf("Updated route discovery timer for %d.%d.%d.%d, retries: %d\n",
                   (destination_ip >> 24) & 0xFF, (destination_ip >> 16) & 0xFF, 
                   (destination_ip >> 8) & 0xFF, destination_ip & 0xFF,
                   pending_routes[i].rreq_retries);
            return;
        }
    }
    
    // 如果没有现有定时器，创建新的路由发现定时器
    for (int i = 0; i < MAX_PENDING_ROUTES; i++) {
        if (pending_routes[i].destination_ip == 0) { // 找到空槽位
            pending_routes[i].destination_ip = destination_ip;
            pending_routes[i].rreq_retries = 1;      // 初始重试次数为1
            pending_routes[i].expiration_time = get_current_time() + aodv_config.rreq_retry_timeout;
            printf("Created route discovery timer for %d.%d.%d.%d\n",
                   (destination_ip >> 24) & 0xFF, (destination_ip >> 16) & 0xFF, 
                   (destination_ip >> 8) & 0xFF, destination_ip & 0xFF);
            return;
        }
    }
    
    // 如果没有可用的槽位，打印警告信息
    printf("No space for new route discovery timer\n");
}

/**
 * @brief 取消指定目标的路由发现定时器
 * 
 * 当成功找到路由或不再需要查找路由时，取消相应的定时器
 * 以避免不必要的RREQ消息发送和资源消耗
 * 
 * @param destination_ip 需要取消路由发现的目标节点IP地址
 */
void cancel_route_discovery_timer(uint32_t destination_ip) {
    // 遍历查找对应目标的定时器
    for (int i = 0; i < MAX_PENDING_ROUTES; i++) {
        if (pending_routes[i].destination_ip == destination_ip) {
            // 清空槽位，释放资源
            pending_routes[i].destination_ip = 0; // 标记为空闲
            pending_routes[i].rreq_retries = 0;
            pending_routes[i].expiration_time = 0;
            printf("Cancelled route discovery timer for %d.%d.%d.%d\n",
                   (destination_ip >> 24) & 0xFF, (destination_ip >> 16) & 0xFF, 
                   (destination_ip >> 8) & 0xFF, destination_ip & 0xFF);
            break;
        }
    }
    // 注意：如果没有找到对应目标的定时器，函数将静默返回
}

/**
 * @brief 检查路由发现定时器并在需要时重新发送RREQ
 * 
 * 实现AODV协议中的路由发现超时处理和重试机制。该函数通常由定时器
 * 定期调用，检查所有待处理的路由发现请求是否超时，并根据情况决定
 * 是重试路由发现还是宣布失败
 * 
 * 重试策略遵循AODV协议规范，使用指数退避算法增加超时时间
 */
void check_and_resend_rreq() {
    uint32_t current_time = get_current_time();
    
    // 遍历所有待处理的路由发现请求
    for (int i = 0; i < MAX_PENDING_ROUTES; i++) {
        // 检查是否有活动的路由发现请求且已超时
        if (pending_routes[i].destination_ip != 0 && 
            current_time >= pending_routes[i].expiration_time) {
            
            uint32_t dest_ip = pending_routes[i].destination_ip;
            int retries = pending_routes[i].rreq_retries;
            
            // 场景一：检查是否超过最大重试次数
            if (retries > aodv_config.max_rreq_retries) {
                printf("Route discovery failed for %d.%d.%d.%d after %d retries\n",
                       (dest_ip >> 24) & 0xFF, (dest_ip >> 16) & 0xFF, 
                       (dest_ip >> 8) & 0xFF, dest_ip & 0xFF,
                       retries);
                
                // 清除定时器，释放资源
                pending_routes[i].destination_ip = 0;
                pending_routes[i].rreq_retries = 0;
                pending_routes[i].expiration_time = 0;
                
                // 通知上层路由发现失败
                // 简化处理，实际实现中可能需要回调或事件通知机制
                printf("Notification: No route to %d.%d.%d.%d\n",
                       (dest_ip >> 24) & 0xFF, (dest_ip >> 16) & 0xFF, 
                       (dest_ip >> 8) & 0xFF, dest_ip & 0xFF);
            } else {
                // 场景二：重新发起路由发现请求
                printf("Retrying route discovery for %d.%d.%d.%d, attempt %d\n",
                       (dest_ip >> 24) & 0xFF, (dest_ip >> 16) & 0xFF, 
                       (dest_ip >> 8) & 0xFF, dest_ip & 0xFF,
                       retries);
                
                // 注意：这里可以实现指数退避算法，增加每次重试的超时时间
                // 目前简化实现，使用固定超时
                initiate_route_discovery(dest_ip);
            }
        }
    }
}

// 获取当前时间（毫秒）
// 注意：这是一个简化实现，实际应该使用系统时间函数
uint32_t get_current_time(void) {
    // 在实际实现中，这里应该返回真实的系统时间
    static uint32_t current_time = 0;
    current_time += 100; // 每次调用增加100毫秒（用于测试）
    return current_time;
}

/**
 * @brief 发送HELLO消息用于邻居发现和维护
 * 
 * 实现AODV协议中的HELLO消息机制，定期向网络广播自身存在
 * 以帮助邻居节点更新其邻居表和检测链路状态
 * 
 * HELLO消息是AODV中维护网络拓扑动态性的关键机制，通过周期性
 * 发送，节点能够快速检测到链路故障
 */
void send_hello_message() {
    // 构造HELLO消息
    hello_message_t hello;
    hello.type = MESSAGE_TYPE_HELLO;              // 消息类型：HELLO
    hello.flags = 0;                              // 初始标志位
    hello.reserved = 0;                           // 保留字段
    hello.hop_count = 0;                          // HELLO消息的跳数总是0（只在一跳范围内有效）
    hello.destination_ip = my_ip;                 // 目标IP为自身
    hello.destination_seq_num = current_seq_num;  // 使用当前节点序列号
    hello.originator_ip = my_ip;                  // 源IP为自身
    hello.lifetime = aodv_config.hello_interval;  // 消息生命周期
    
    // 广播HELLO消息给所有邻居节点
    net_interface_broadcast(PROTOCOL_AODV, (void *)&hello, sizeof(hello_message_t));
    
    // 更新邻居表中所有节点的超时时间
    // 这是一种简化实现，实际中应该只更新那些回复了HELLO的邻居
    // 使用hello_interval和allowed_hello_loss计算邻居超时时间
    neighbor_table_update_all_timeouts(get_current_time() + (aodv_config.hello_interval * aodv_config.allowed_hello_loss));
    
    printf("Sent HELLO message\n");
}

/**
 * @brief 设置AODV协议的配置参数
 * 
 * 提供外部接口允许用户自定义AODV协议的各种参数，如超时时间、
 * 重试次数、消息间隔等。这些参数直接影响协议的性能和行为
 * 
 * @param config 包含AODV协议配置参数的结构体指针
 */
void aodv_set_config(const aodv_config_t *config) {
    if (config != NULL) {
        // 安全地复制配置参数
        memcpy(&aodv_config, config, sizeof(aodv_config_t));
    }
    // 注意：实际实现中可能需要对参数进行有效性检查
}

/**
 * @brief 获取当前AODV协议的配置参数
 * 
 * 提供外部接口允许查询当前AODV协议的配置状态，用于监控和调试
 * 
 * @return 指向当前AODV配置结构体的常量指针
 */
const aodv_config_t *aodv_get_config(void) {
    return &aodv_config;
}

// 打印统计信息
void aodv_print_stats(void) {
    printf("\n=== AODV Statistics ===\n");
    printf("My IP: %d.%d.%d.%d\n", 
           (my_ip >> 24) & 0xFF, (my_ip >> 16) & 0xFF, 
           (my_ip >> 8) & 0xFF, my_ip & 0xFF);
    printf("Current Sequence Number: %u\n", current_seq_num);
    printf("Last RREQ ID: %u\n", last_rreq_id);
    printf("========================\n\n");
}